package com.antd.admin.server.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.antd.admin.api.dto.UserDTO;
import com.antd.admin.api.entity.SysRole;
import com.antd.admin.api.entity.SysUser;
import com.antd.admin.api.entity.SysUserRole;
import com.antd.admin.server.mapper.SysUserMapper;
import com.antd.admin.server.service.*;
import com.antd.common.auth.util.AntdSecurityUtil;
import com.antd.common.core.constant.AntdConstant;
import com.antd.common.core.exception.BaseException;
import com.antd.common.data.datascope.DataScope;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author 子丶沫
 * @since 2020-11-18
 */
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements ISysUserService {
    @Autowired
    private ISysMenuService menuService;
    @Autowired
    private ISysRoleService roleService;
    @Autowired
    private ISysDeptService deptService;
    @Autowired
    private ISysUserRoleService userRoleService;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Override
    public SysUser findByUsername(String username) {
        SysUser user = baseMapper.selectOne(Wrappers.<SysUser>query()
                .lambda()
                .select(SysUser::getUserId, SysUser::getUsername, SysUser::getPassword, SysUser::getLockFlag,SysUser::getAvatar,SysUser::getDeptId)
                .eq(SysUser::getUsername, username).or().eq(SysUser::getPhone,username));
       return buildUser(user);
    }
    private SysUser buildUser(SysUser sysUser){
        if(ObjectUtil.isNotNull(sysUser)){
            Set<String> permission = menuService.findPermissionByUserId(sysUser.getUserId())
                    .stream().filter(StrUtil::isNotEmpty)
                    .map(data->data.split(","))
                    .flatMap(Arrays::stream)
                    .collect(Collectors.toSet());
            List<SysRole> roleList = roleService.findRoleByUserId(sysUser.getUserId());
            Set<String> roles =roleList
                    .stream().map(role -> "ROLE_" + role.getRoleId()).collect(Collectors.toSet());
            permission.addAll(roles);
            sysUser.setPermissions(permission);
            sysUser.setRoles(roleList);
            return sysUser;
        }
        return null;
    }
    @Override
    public SysUser findByUserMobile(String mobile) {
        SysUser user = baseMapper.selectOne(Wrappers.<SysUser>query()
                .lambda()
                .select(SysUser::getUserId, SysUser::getUsername, SysUser::getPassword, SysUser::getLockFlag,SysUser::getAvatar,SysUser::getDeptId)
                .eq(SysUser::getPhone, mobile));
        return buildUser(user);
    }

    @Override
    public IPage<SysUser> queryUserList(IPage<SysUser> page, UserDTO userDTO) {
        if(ObjectUtil.isNotNull(userDTO)&&ObjectUtil.isNotNull(userDTO.getDeptId())){
            List<String> deptIds = deptService.queryDeptIds(userDTO.getDeptId());
            userDTO.setDeptList(deptIds);
        }
        return baseMapper.findUserVoPage(page,userDTO,new DataScope());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int saveUser(UserDTO userDTO) {
        SysUser user=new SysUser();
        BeanUtils.copyProperties(userDTO,user);
        String password = AntdSecurityUtil.encodePassword(user.getPassword());
        user.setPassword(password);
        int insert = baseMapper.insert(user);
        List<String> roleIds = userDTO.getRoleList();
        List<SysUserRole> userRoleList = roleIds.stream()
                .map(roleId -> new SysUserRole().setRoleId(roleId).setUserId(user.getUserId())).collect(Collectors.toList());
        userRoleService.saveBatch(userRoleList);
        return insert;
    }

    @Override
    public int updateUser(UserDTO userDTO) {
        SysUser sysUser=new SysUser();
        BeanUtil.copyProperties(userDTO,sysUser);
        int update = baseMapper.updateById(sysUser);
        LambdaUpdateWrapper<SysUserRole> wrapper =Wrappers.lambdaUpdate();
        wrapper.eq(SysUserRole::getUserId,sysUser.getUserId());
        userRoleService.remove(wrapper);
        List<String> roleIds = userDTO.getRoleList();
        List<SysUserRole> userRoleList = roleIds.stream()
                .map(roleId -> new SysUserRole().setRoleId(roleId).setUserId(sysUser.getUserId())).collect(Collectors.toList());
        userRoleService.saveBatch(userRoleList);
        return update;
    }

    @Override
    public int deleteUser(List<String> idList) {
        idList.forEach(userId->{
            if(userId.equals("1")){
                throw new BaseException("不能删除超级管理员");
            }
            int i = baseMapper.deleteById(userId);
            if(i>0){
                LambdaUpdateWrapper<SysUserRole> wrapper = Wrappers.lambdaUpdate();
                wrapper.eq(SysUserRole::getUserId,userId);
                userRoleService.remove(wrapper);
            }
        });
        return 1;
    }

    @Override
    public boolean checkUniqueness(String value, String oldValue) {
        if(StrUtil.isNotBlank(oldValue)){
            if(value.equals(oldValue)){
                return false;
            }
        }
        List<SysUser> userList = baseMapper.selectList(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getUsername, value).or().eq(SysUser::getPhone,value));
        return userList.size()>0;
    }

    @Override
    public int register(UserDTO userDTO,String t,String code) {
        if(StrUtil.isBlank(code)){
            throw new BaseException("验证码不能为空");
        }
        String oldCode = redisTemplate.opsForValue().get(AntdConstant.IMAGE_KEY + t);
        if(StrUtil.isBlank(oldCode)){
            throw new BaseException("验证码已失效");
        }
        if(!StrUtil.equalsIgnoreCase(code,oldCode)){
            throw new BaseException("验证码错误");
        }
        redisTemplate.delete(AntdConstant.IMAGE_KEY + t);
        userDTO.setDeptId("4");
        userDTO.setRoleList(Collections.singletonList("7"));
        userDTO.setJobId("5");
        SysUser user=new SysUser();
        BeanUtils.copyProperties(userDTO,user);
        user.setPassword(AntdSecurityUtil.encodePassword(user.getPassword()));
        baseMapper.insert(user);
        List<String> roleIds = userDTO.getRoleList();
        List<SysUserRole> userRoleList = roleIds.stream()
                .map(roleId -> new SysUserRole().setRoleId(roleId).setUserId(user.getUserId())).collect(Collectors.toList());
        userRoleService.saveBatch(userRoleList);
        return 1;
    }

}
